<?php
//ver 1.1
namespace huge\plugin;
class SocialLogin{
    public static function init(string $type, array $config){
        switch ($type) {
            case 'qq':
                return new QQ($config);
            case 'gitee':
                return new Gitee($config);
            case 'wechat':
                return new Wechat($config);
            default :
                return false;
        }
    }
}
class tool{
    public static function sendPost($url, array $data){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        $response = curl_exec($curl);
        curl_close($curl);
        return $response;
    }
    public static function randString(int $length = 32, int $type = 4): string {
        $rand = '';
        $randstr = match ($type) {
            1 => '0123456789',
            2 => 'abcdefghijklmnopqrstuvwxyz',
            3 => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
            default => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
        };
        $max = strlen($randstr) - 1;
        mt_srand((double)microtime() * 1000000);
        for ($i = 0; $i < $length; $i++) {
            $rand .= $randstr[mt_rand(0, $max)];
        }
        return $rand;
    }
}
class QQ{
    private $clientId, $clientSecret, $redirectUri;
    public function __construct($config){
        $this->clientId = $config['QQ_CLIENT_ID'];
        $this->clientSecret = $config['QQ_CLIENT_SECRET'];
        $this->redirectUri = $config['QQ_REDIRECT_URI'];
    }

    /**
     * @return string 登录链接
     */
    public function getAuthorizationCode() : string {
        $url = "https://graph.qq.com/oauth2.0/authorize";
        $state = tool::randString();
        $data = [
            "response_type" => "code",
            "client_id" => $this->clientId,
            "redirect_uri" => $this->redirectUri,
            "state" => $state,
            "scope" => "get_user_info",
        ];
        return file_get_contents($url . "?" . http_build_query($data));
    }

    /**
     * @param $code
     * @return array
     */
    public function getAccessToken($code) : string {
        $url = "https://graph.qq.com/oauth2.0/token";
        $data = [
            "grant_type" => "authorization_code",
            "client_id" => $this->clientId,
            "client_secret" => $this->clientSecret,
            "redirect_uri" => $this->redirectUri,
            "code" => $code,
            "fmt" => "json"
        ];
        $response = file_get_contents($url . "?" . http_build_query($data));
        return json_decode($response, true)["access_token"];
    }

    /**
     * @param $access_token
     * @return string
     */
    public function getOpenId($access_token) :string {
        $url = "https://graph.qq.com/oauth2.0/me";
        $data = [
            "access_token" => $access_token,
            "fmt" => "json",
        ];
        $response = file_get_contents($url . "?" . http_build_query($data));
        return json_decode($response, true)["openid"];
    }
}
class Gitee{
    private $clientId, $clientSecret, $redirectUri;
    public function __construct($config){
        $this->clientId = $config['GITEE_CLIENT_ID'];
        $this->clientSecret = $config['GITE_CLIENT_SECRET'];
        $this->redirectUri = $config['GITE_REDIRECT_URI'];
    }

    /**
     * @return string 登录链接
     */
    public function getAuthorizationCode() : string {
        return "https://gitee.com/oauth/authorize?client_id=" . $this->clientId . "&redirect_uri=" . $this->redirectUri . "&response_type=code";
    }
    public function getAccessToken($code) :string {
        $url = "https://gitee.com/oauth/token";
        $data = [
            "grant_type" => "authorization_code",
            "code" => $code,
            "client_id" => $this->clientId,
            "client_secret" => $this->clientSecret,
            "redirect_uri" => $this->redirectUri,
        ];
        $response = file_get_contents($url . "?" . http_build_query($data));
        return json_decode($response, true)["access_token"];
    }
    public function getOpenId($access_token) :string {
        $url = "https://gitee.com/api/v5/user";
        $data = [
            "access_token" => $access_token,
        ];
        $response = file_get_contents($url . "?" . http_build_query($data));
        return json_decode($response, true)["id"];
    }
}
class Wechat{
    private $appid, $appsecret, $redirectUri;
    public function __construct($config){
        $this->appid = $config['WECHAT_APPID'];
        $this->appsecret = $config['WECHAT_APPSECRET'];
        $this->redirectUri = $config['WECHAT_REDIRECT_URI'];
    }

    /**
     * @return string
     */
    public function getAuthorizationCode() : string {
        return "https://open.weixin.qq.com/connect/qrconnect?appid=" . $this->appid . "&redirect_uri=" . urlencode($this->redirectUri) . "&response_type=code&scope=snsapi_login&state=" . rand(0000, 9999) . "#wechat_redirect";
    }

    /**
     * @param $code
     * @return string
     */
    public function getAccessToken($code) : string {
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" . $this->appid . "&secret=" . $this->appsecret . "&code=" . $code . "&grant_type=authorization_code";
        $response = file_get_contents($url);
        return json_decode($response, true)["access_token"];
    }

    /**
     * @param $code
     * @return string
     */
    public function getOpenId($code) :string {
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" . $this->appid . "&secret=" . $this->appsecret . "&code=" . $code . "&grant_type=authorization_code";
        $response = file_get_contents($url);
        return json_decode($response, true)["openid"];
    }
}